/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { Scene, SceneConfig } from "../../ArkAnalyzer/src";
import { GraphBuilder } from "../../Ark2Graph/graphBuilder";
import { Node } from "../../Ark2Graph/Nodes";
import { CfgEdge, DfgEdge, CgEdge } from "../../Ark2Graph/Edge";
import { Stmt } from "../../ArkAnalyzer/src/core/base/Stmt";
import { describe, expect, test } from "@jest/globals";
import path from "path";
import fs from "fs";
import { Connection } from "../../Ark2Graph/Client";

const testConfigs = [
  "IntegrationTest1Config.json",
  "IntegrationTest2Config.json",
  "IntegrationTest3Config.json",
  "IntegrationTest4Config.json",
  "IntegrationTest5Config.json",
];

describe.each(testConfigs)("Integration Test with %s", (configFile: string) => {
  let client: any;
  let graphBuilder: GraphBuilder;
  let CFGCount: any;
  let DFGCount: any;
  let CGCount: any;
  let NodeCount: any;

  const CFGquery = `.E().has('type', 'cfg').count()`;
  const DFGquery = `.E().has('type', 'dfg').count()`;
  const CGquery = `.E().has('type', 'cg').count()`;
  const Nodequery = `.V().count()`;

  beforeAll(async () => {
    // 确保每次测试前数据库是干净的
    client = await Connection.getClient();
    await client.submit('g.V().drop()');
    
    const configPath = path.resolve(
      __dirname,
      `../test_config/IntegrationTest/${configFile}`
    );
    graphBuilder = new GraphBuilder(client, configPath);
    const configfile = JSON.parse(fs.readFileSync(configPath, "utf-8"));
    const filePath = configfile.fileTestConfigPath;
    let config: SceneConfig = new SceneConfig();
    config.buildFromJson(filePath);
    config.buildFromProjectDir(config.getTargetProjectDirectory());
    let scene = new Scene();
    scene.buildSceneFromProjectDir(config);
    graphBuilder.setScene(scene);
    await graphBuilder.buildCPG();
    let cypherBatch = "g";
    CFGCount = await client.submit(cypherBatch + CFGquery);
    DFGCount = await client.submit(cypherBatch + DFGquery);
    CGCount = await client.submit(cypherBatch + CGquery);
    NodeCount = await client.submit(cypherBatch + Nodequery);
  });

  afterAll(async () => {
    // 清理所有节点和边
    await client.submit('g.V().drop()');
    await client.close();
  });

  test("should initialize GraphBuilder correctly", () => {
    expect(graphBuilder).toBeDefined();
  });

  // Expected values for each test config
  const expectedValues = {
    "IntegrationTest1Config.json": { cfg: 31, dfg: 28, cg: 3, nodes: 32 },
    "IntegrationTest2Config.json": { cfg: 21, dfg: 12, cg: 2, nodes: 21 },
    "IntegrationTest3Config.json": { cfg: 24, dfg: 21, cg: 2, nodes: 24 },
    "IntegrationTest4Config.json": { cfg: 30, dfg: 26, cg: 4, nodes: 30 },
    "IntegrationTest5Config.json": { cfg: 31, dfg: 22, cg: 2, nodes: 31 },
  };

  test("should build CFG edges correctly", () => {
    expect(CFGCount._items[0]).toBe(
      expectedValues[configFile as keyof typeof expectedValues].cfg
    );
  });

  test("should build DFG edges correctly", () => {
    expect(DFGCount._items[0]).toBe(
      expectedValues[configFile as keyof typeof expectedValues].dfg
    );
  });

  test("should build CG edges correctly", () => {
    expect(CGCount._items[0]).toBe(
      expectedValues[configFile as keyof typeof expectedValues].cg
    );
  });

  test("should add nodes correctly", () => {
    expect(NodeCount._items[0]).toBe(
      expectedValues[configFile as keyof typeof expectedValues].nodes
    );
  });
});
